最后更新时间:2019年6月17日
功能介绍
MapGIS Mobile 10.3基于高性能的移动三维渲染引擎与C++移动三维内核,提供移动端全空间真三维应用功能,全面支持离线与在线的矢量、影像、DEM、栅格瓦片、模型、IGServer地图服务、第三方地图服务等各种数据,以及支持场景球面与平面模式等场景管理功能,提供场景漫游、地形贴合、多种场景覆盖物等多种功能,满足移动端真三维应用需求。
MapGIS Mobile for Android移动三维开发平台提供了多种功能,当然这些功能的基础就是三维场景的展示,三维功能的展示都是依托于场景的显示,接下来学习三维场景展示的相关介绍。
开发者可通过该功能,实现移动端加载离线三维矢量数据。支持直接加载shp格式的离线矢量数据,须将数据拷贝到移动设备。
开发者可通过该功能,实现移动端加载离线三维地形数据。支持直接加载tif格式的离线三维地形数据,须将数据拷贝到移动设备。
开发者可通过该功能,实现移动端加载离线三维影像数据。支持直接加载tif等格式的离线三维影像数据,须将数据拷贝到移动设备。
开发者可通过该功能,实现移动端加载离线三维模型数据。支持移动端加载常用的开放三维模型,如obj、ive、3ds等格式的三维模型数据。
开发者可通过该功能,实现移动端在三维场景中加载IGServer二维矢量服务地图,须通过MapGIS IGServer发布可用的二维矢量地图服务。
开发者可通过该功能,实现移动端在三维场景中加载IGServer二维瓦片服务地图,须通过MapGIS IGServer发布可用的二维瓦片地图服务。
开发者可通过该功能,实现移动端在三维场景中加载IGServer三维服务地图,须通过MapGIS IGServer发布可用的三维地图服务。
开发者可通过该功能,实现移动端在三维场景中加载在线WMS服务地图,可通过MapGIS IGServer或第三方发布可用的WMS服务。
开发者可通过该功能,实现移动端在三维场景中加载第三方在线TMS服务,须确保在线TMS服务可正常调用。
开发者可通过该功能,实现移动端在三维场景中加载第三方在线Google地图服务,须确保在线Google地图服务可正常调用。
数据类型
MapGIS Mobile for Android三维开发平台提供多种类型的三维场景数据,如下图所示,后续会讲解每种数据的展示如何实现。
基本原理
移动端三维场景展示与MapGIS桌面平台软件中场景展示的设计相对应,均通过地图文档—场景—图层来组织,采用一个场景视图控件(com.zondy.mapgis.android.sceneview.SceneView)作为容器装载三维场景,调用其相关接口就可加载三维场景地图。同时,移动端三维场景展示的与二维地图显示的原理也类似。
场景中图层数据组织关系如下图所示:
在场景视图中加载一个三维场景,通过各数据图层分别加载不同的数据,即通过三维矢量图层(VectorLayer3D)、三维地形图层(TerrainLayer3D)、地图引用图层(MapRefLayer)、三维模型图层(ModelLayer3D)加载对应的离线数据,包括MapGIS移动端地图数据(矢量、栅格、高程、模型等数据)、倾斜摄影数据等;通过服务图层(ServerLayer3D)加载各类在线地图数据,如IGServer发布的二维地图与三维地图服务、OGC服务、第三方公共地图服务如天地图、Google地图等。
功能接口
场景展示功能对应API程序包为com.zondy.mapgis.android.sceneview中的核心类SceneView,以及com.zondy.mapgis.core.scene包中的Scene、Layer3D、GroupLayer3D、ServerLayer3D、VectorLayer3D、TerrainLayer3D等,核心接口如下所示:
接口 | 说明 |
---|---|
SceneView.setScene() | 设置场景 |
SceneView.setSceneAsync() | 设置场景(异步方法) |
Scene.addLayer() | 在场景中添加三维图层 |
Layer3D.setDriverType() | 设置图层驱动类型 |
Layer3D.setSRSByString() | 设置图层参考系 |
基本流程
1
实现三维场景展示之前,首先需要准备需显示的三维数据,以离线矢量数据为例,MapGIS Mobile支持直接加载.shp格式矢量数据,用户可以准备一份shp数据,然后直接拷贝到移动设备的存储中。
2
以Android Studio作为开发工具,创建工程。
项目创建完成之后,需要为应用程序添加需要的移动设备资源使用权限。实现三维场景展示功能,首先需要进行MapGIS的环境初始化、授权操作,加载离线或者在线地图,所以需要应用具备读/写手机存储的权限、联网权限、读取手机状态的权限。在“AndroidManifest.xml”程序清单文件中编写对应权限标签。
<!-- 允许应用程序向外部存储写入数据 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 允许应用程序读取外部存储数据 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 允许对移动存储安装和卸载文件系统 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 允许应用程序只读访问手机状态 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 允许应用程序访问网络,可能产生GPRS流量 --> <uses-permission android:name="android.permission.INTERNET" />
说明:在应用程序的targetSdkVersion版本大于等于23,手机的Android系统版本大于等于6.0时,对于读写手机存储、读取手机状态等危险权限,需要在Java代码中通过代码来动态申请权限。
3
项目创建完成后,在实现三维场景功能实现之前,需要向工程中导入MapGIS的开发库。从云生态圈的开发世界中获取MapGIS Mobile for Android二次开发包,其中libs文件夹中的文件就是实现MapGIS移动GIS功能需要的具体开发库,包括jar包和so库两部分,使用时需将其引入到项目中。libs下的开发库如下图所示:
对于三维功能,需要使用MapGISMobileBase.jar(用于环境初始化、授权)、MapGISMobileScene.jar(核心库)、MapGISMobileMap.jar(用于二维地图相关功能)三个开发包,所以需要将这三个jar包以及对应的so库导入到工程中。
(1) 导入jar包:切换工程目录结构为“Project”模式,将jar包拷贝到工程的“app\libs”目录下。添加完成之后,选择加入的jar包,右键单击,在弹出的菜单中选择“Add As Library”,弹出“Create Library”对话框,选择app模块,点击“OK”即可。等待项目同步更新完成,查看当前module中的“build.gradle”脚本文件,发现其中在dependencies标签中增加了jar的依赖,到此完成jar包的导入。
(2) 导入so库:首先将SDK中libs目录下的armeabi、armeabi-v7a、arm64-v8a文件夹拷贝到模块module的libs目录下,剔除不需要的so库,只保留与MapGISMobileBase.jar、MapGISMobileScene.jar、MapGISMobileMap.jar对应的so即可。如果已有armeabi和armeabi-v7a目录,则直接将*.so库文件复制到对应的目录中。
然后打开对应module下的build.gradle脚本文件,在android标签中,添加如下代码,完成后sync同步工程即可。
sourceSets { main { jniLibs.srcDirs = ['libs']; } }
4
要使用MapGIS移动平台提供的功能,导入开发库后,还需要初始化MapGIS环境、请求移动端授权,这样GIS功能才能得以使用。移动开发授权功能对应的API程序包为com.zondy.mapgis.android.environment,使用环境类(Environment)的接口方法实现。
在工程中展开src的目录,打开MainActivity.java文件,先获取移动设备SD卡上放置地图数据文件的路径,然后调用Environment的initialize()进行环境初始化,调用requestAuthorization()请求授权。使用MapGIS Mobile提供的功能接口之前,首先必须进行环境初始化和授权验证。
initialize(java.lang.String strRootPath, Context context) 环境初始化,必须在使用SDK各组件之前调用,会自动建立根目录结构 requestAuthorization(Context context,Environment.AuthorizeCallback callback) 请求授权
说明:调用initialize()进行环境初始化,必须在使用SDK各组件之前调用,会自动建立根目录结构。
核心代码如下:
//环境目录路径 String strRootPath = android.os.Environment.getExternalStorageDirectory().getPath() + "/MapGIS Mobile 3D Sample/"; //环境初始化,必须在使用SDK各组件之前调用,会自动建立根目录结构 Environment.initialize(strRootPath, getApplicationContext()); //请求授权 Environment.requestAuthorization(this, new Environment.AuthorizeCallback() { @Override public void onComplete() { System.out.println("授权完成"); } });
5
在界面布局文件中添加一个场景视图控件(SceneView)。展开工程中的res/layout目录,编辑activity_main.xml文件,初始化加载一个SceneView视图(com.zondy.mapgis.android.sceneview.SceneView)并设置其ID、高、宽属性。
代码如下:
<com.zondy.mapgis.android.sceneview.SceneView android:id="@+id/sceneView" android:layout_width="match_parent" android:layout_height="match_parent"> </com.zondy.mapgis.android.sceneview.SceneView>
添加场景视图控件之后,可以跳过接下来的步骤6,不编写场景加载代码,直接调试运行程序,同样能够看到三维场景视图,默认添加了地球影像,对场景中三维球进行用于显示的底图渲染。
6
打开工程中src下的MainActivity.java文件,在请求授权成功回调函数中编写加载离线shp矢量数据的代码,完整代码如下所示:
public class MainActivity extends AppCompatActivity { //定义场景视图、场景对象 private SceneView sceneView; private Scene scene; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //实例化场景视图 sceneView = findViewById(R.id.sceneView); //环境目录路径 String strRootPath = android.os.Environment.getExternalStorageDirectory().getPath() + "/MapGIS Mobile 2D Sample/"; //环境初始化,必须在使用SDK各组件之前调用,会自动建立根目录结构 Environment.initialize(strRootPath, getApplicationContext()); //请求授权 Environment.requestAuthorization(this, new Environment.AuthorizeCallback() { @Override public void onComplete() { System.out.println("授权完成"); VectorLayer3D vectorLayer3D = new VectorLayer3D(); //为图层设置名称 vectorLayer3D.setName("离线矢量数据"); //为图层设置驱动类型(OGR数据驱动.用于离线矢量数据的读取) vectorLayer3D.setDriverType(DriverType.Driver_Type_OGR); //为图层设置URL vectorLayer3D.setURL(android.os.Environment.getExternalStorageDirectory().getPath() + "/MapGIS Mobile 3D Sample/Scene/Ocean/haiyang.shp"); //实例化场景、三维矢量图层 scene = new Scene(); //为场景添加图层 scene.addLayer(vectorLayer3D); //为场景视图设置无光照模式 sceneView.setSunLightingMode(SunLightingMode.NONE); //为场景视图设置场景 sceneView.setSceneAsync(scene, new SceneView.SceneFinishCallback() { @Override public void onDidFinish(boolean b) { if (b) { Toast.makeText(MainActivity.this, "场景加载成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MainActivity.this, "场景加载失败", Toast.LENGTH_SHORT).show(); } } }); } }); } }
7
单击菜单栏上的Run|Run ‘app’,或者工具栏上的 图标,在弹出的对话框中选择目标设备(模拟器或者真机),单击“OK”按钮,即可将项目安装到移动设备上。
将项目安装到模拟器或者手机上,并运行。若初次运行基于MapGIS Mobile 10.3开发的app,将在app中弹出对话框进行授权认证,许可认证后的移动端设备再次运行使用此app则不会再弹框认证。
例如,在真机上运行app,确保地图数据已经拷贝到手机的SD卡目录下,初次运行时弹出对话框进行授权认证,输入有效的司马云开发者账号、密码,许可认证成功后进入场景展示界面。